package gcr

import (
	_ "embed"
	"io"
	"os"
	"fmt"
	"html"
	"bytes"
	"os/exec"
	"reflect"
	"strconv"
	"strings"
	"kumachan/standalone/qt"
	"kumachan/standalone/util"
)


func Exec(argv ([] string)) {
	var program = argv[0]
	var args = argv[1:]
	var cmd = exec.Command(program, args...)
	var buf bytes.Buffer
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = io.MultiWriter(os.Stderr, &(buf))
	var err = cmd.Start()
	if err != nil { panic(err) }
	_ = cmd.Wait()
	var code = cmd.ProcessState.ExitCode()
	if code == 0 {
		os.Exit(0)
	} else {
		var info = fmt.Sprintf (
			"<b>Program:</b><p>%s</p>" +
			"<b>Exit Code:</b><p>%s</p>" +
			"<b>Error Output:</b><pre>%s</pre>",
			html.EscapeString(argvQuote(argv)),
			html.EscapeString(strconv.Itoa(code)),
			html.EscapeString(stderrDisplay(buf.String())),
		)
		setupReportDialog(info)
	}
}
func argvQuote(argv ([] string)) string {
	var quoted = make([] string, len(argv))
	for i, item := range argv {
		quoted[i] = strconv.Quote(item)
	}
	return strings.Join(quoted, " ")
}
func stderrDisplay(content string) string {
	var buf strings.Builder
	var parts = strings.Split(content, "\033[")
	for _, part := range parts {
		var m = strings.IndexRune(part, 'm')
		if m != -1 {
			var _, err = strconv.Atoi(part[:m])
			if err == nil {
				part = part[(m+1):]
			}
		}
		buf.WriteString(part)
	}
	return buf.String()
}

//go:embed gcr.ui
var uiDefXml string
type reportDialog struct {
	Dialog   qt.Dialog
	Widgets  reportDialogWidgets
}
type reportDialogWidgets struct {
	TextDisplay  qt.TextBrowser
}
func setupReportDialog(html string) {
	var ui reportDialog
	var err = qt.LoadWidget(uiDefXml, util.ExeDir(), func(root qt.Widget) error {
		var err1 = root.ExactlyAssignTo(reflect.ValueOf(&ui.Dialog))
		if err1 != nil { return err1 }
		var err2 = root.ExactlyAssignChildrenTo(reflect.ValueOf(&ui.Widgets))
		if err2 != nil { return err2 }
		return nil
	})
	if err != nil { panic(err) }
	ui.Dialog.OnRejected(func() {
		os.Exit(0)
	})
	qt.CommitTask(func() {
		ui.Widgets.TextDisplay.SetHtml(html)
		ui.Dialog.MoveToScreenCenter()
		ui.Dialog.Show()
	})
}


